// compile with:
//   gcc -Wall -o cairo_print cairo_print.c `pkg-config --cflags --libs cairo` `cups-config --cflags --libs`

#include <stdio.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <cups/cups.h>
#include <cairo/cairo.h>
#include <cairo/cairo-ps.h>

using namespace std;

// A4 width, height in points, from GhostView manual:
//   http://www.gnu.org/software/gv/manual/html_node/Paper-Keywords-and-paper-size-in-points.html
#define WIDTH  595
#define HEIGHT 842

string createField(string fieldStr)
{
    size_t fieldSz  = 10;
    string field = string(fieldSz, ' ');
    //    cout << "|" << field << "|" << endl;
    //    string num = "12";
    field.replace(0, fieldStr.size(), fieldStr);
    //    cout << "|" << header << "|" << endl;
    return field;
}

//http://stackoverflow.com/questions/11719538/how-to-use-stringstream-to-separate-comma-separated-strings
string createRow(string row, string delimiter)
{
    std::istringstream ss(row);
    std::string token;
    string field = "";
    while(std::getline(ss, token, ',')) {
        //        std::cout << token << '\n';
        field += delimiter + createField(token);
    }
    field += delimiter;
    //    cout << field;
    //    cout << endl;
    return field;
}

int main(int argc, char** argv) {
    if (argc!= 2){
        fprintf (stderr, "usage: %s word\n", argv[0]);
        return 1;
    }

    string mas = "+";
    string bar = "|";
//    std::ifstream file("/tmp/reporte20140129110216.csv");
    std::ifstream file(argv[1]);
    std::string temp;
    string s = "";
    vector<string> rows;
    s = "----------,----------,----------,----------";
    rows.push_back(createRow(s, mas));
    s = "Mesa,Rentas,Minutos,S/.";
    rows.push_back(createRow(s, bar));
    s = "----------,----------,----------,----------";
    rows.push_back(createRow(s, mas));
    while(std::getline(file, temp)) {
        s = createRow(temp, bar);
        cout << s << endl;
        rows.push_back(s);
    }
    s = "----------,----------,----------,----------";
    rows.push_back(createRow(s, mas));

    // setup
    char* tmpfilename = tempnam(NULL,NULL);
    cairo_surface_t* surface = cairo_ps_surface_create(tmpfilename,
                                                       WIDTH,
                                                       HEIGHT);
    cairo_t *context = cairo_create(surface);

    // draw some text
    cairo_select_font_face(context,
                           "Monospace",
                           CAIRO_FONT_SLANT_NORMAL,
                           CAIRO_FONT_WEIGHT_NORMAL);
    cairo_set_font_size(context, 20);
    //    cairo_move_to(context, WIDTH/2, HEIGHT/2);
    //    cairo_show_text(context, argv[1]); // the text we got as a parameter

    for (size_t i = 0; i < rows.size(); i++)
    {
        cairo_move_to(context, 20, 80 + i*20);
        cairo_show_text(context, rows.at(i).c_str()); // the text we got as a parameter
    }

    // draw a dotted box
    /*
  const double pattern[] = {15.0, 10.0};
  cairo_set_dash(context, pattern, 2, 0);
  cairo_set_line_width(context, 5);
  cairo_rectangle(context, WIDTH*0.33, HEIGHT*0.33, WIDTH*0.5, WIDTH*0.5);
  cairo_stroke(context);
  */

    // finish up
    cairo_show_page(context);
    cairo_destroy(context);
    cairo_surface_flush(surface);
    cairo_surface_destroy(surface);

    // print
    //  cupsPrintFile(cupsGetDefault(), tmpfilename, "cairo PS", 0, NULL);
    cupsPrintFile("PDF", tmpfilename, "cairo PS", 0, NULL);
    unlink(tmpfilename);

    return 0;
}
